package com.homedo.microservice.open.service.gateway.alert.task;


import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.homedo.common.bean.data.ResponseData;
import com.homedo.common.bean.data.enums.ResponseEnum;
import com.homedo.common.util.Detect;
import com.homedo.common.util.HttpUtility;
import com.homedo.microservice.open.service.gateway.alert.gateway.bean.enums.foralertnotice.StatusEnum4AlertNotice;
import com.homedo.microservice.open.service.gateway.alert.gateway.bean.po.AlertNotice;
import com.homedo.microservice.open.service.gateway.alert.gateway.bean.po.AlertUser;
import com.homedo.microservice.open.service.gateway.alert.gateway.bean.po.Alerting;
import com.homedo.microservice.open.service.gateway.alert.gateway.persistence.dao.AlertNoticeDao;
import com.homedo.microservice.open.service.gateway.alert.gateway.persistence.dao.AlertUserDao;
import com.homedo.microservice.open.service.gateway.alert.gateway.persistence.dao.AlertingDao;
import com.homedo.microservice.open.service.gateway.alert.support.CurAlertingSupportHolder;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 告警通知任务
 */
@Component
public class AlertNoticeTask {

    @Autowired
    private AlertNoticeDao alertNoticeDao;
    @Autowired
    private AlertUserDao alertUserDao;
    @Autowired
    private AlertingDao alertingDao;

    private static final Logger LOGGER = LoggerFactory.getLogger(AlertNoticeTask.class);

    //检测应用
    private DynamicStringProperty applicationNames = DynamicPropertyFactory.getInstance().getStringProperty("alert.applicationNames", "");
    private DynamicStringProperty env = DynamicPropertyFactory.getInstance().getStringProperty("alert.env", "");
    private DynamicStringProperty smsAddr = DynamicPropertyFactory.getInstance().getStringProperty("alert.smsAddr", "http://micro-innerapi.homedo.com/message-service/sms/send");
    private DynamicStringProperty emailAddr = DynamicPropertyFactory.getInstance().getStringProperty("alert.emailAddr", "http://micro-innerapi.homedo.com/message-service/email/send");

    @Scheduled(cron = "0 0/5 * * * ?")
    public void task() {

        this.doSchedule();

    }

    private void doSchedule() {
        if (!Detect.notEmpty(applicationNames.get())) {
            return;
        }

        String[] applicationNameParts = applicationNames.get().split(",");
        for (String applicationNamePart : applicationNameParts) {
            this.dealServiceGateway(applicationNamePart.trim());
        }
    }

    private void dealServiceGateway(String applicationName) {
        AlertNotice record = new AlertNotice();
        record.setStatus((int) StatusEnum4AlertNotice.EFFECTIVE.getCode());
        if (CurAlertingSupportHolder.get() != null) {
            record.setAlertingId(CurAlertingSupportHolder.get());
        }

        List<AlertNotice> alertNotices = alertNoticeDao.getListByRecord(record);
        if (!Detect.notEmpty(alertNotices)) {
            return;
        }

        alertNotices.forEach(e -> {
            if (e.getNoticeCount().intValue() < e.getNoticeTotal()) {
                this.dealNotice(e, applicationName);
            } else {//通知已发送完毕 更新结束状态
                AlertNotice updateRecord = new AlertNotice();
                updateRecord.setId(e.getId());
                updateRecord.setUpdateTime(new Date());
                updateRecord.setStatus((int) StatusEnum4AlertNotice.FINISH.getCode());

                alertNoticeDao.updateByPrimaryKeySelective(updateRecord);
            }
        });
    }

    private void dealNotice(AlertNotice alertNotice, String applicationName) {
        AlertUser alertUser = alertUserDao.getById(alertNotice.getAlertUserId());
        if (alertUser == null) {
            alertUser = new AlertUser();
        }
        Alerting alerting = alertingDao.getById(alertNotice.getAlertingId());

        String content = "【河姆渡】网关告警:（ " + applicationName + "_" + env.get() + "网关 ）通知。服务组：（ " +
                alerting.getServiceId() + " ）,后端服务器（ " + alerting.getUrl() + " ）健康检查异常，服务已离线。请知悉处理！";

        Map<String, String> headParamMap = Maps.newHashMap();
        headParamMap.put("h-x-app-name", DynamicPropertyFactory.getInstance().getStringProperty("spring.application.name", "").get());
        headParamMap.put("h-x-app-key", DynamicPropertyFactory.getInstance().getStringProperty("spring.application.key", "").get());
        headParamMap.put("h-x-app-version", DynamicPropertyFactory.getInstance().getStringProperty("_version", "1.0.0").get());

        try {
            String smsResponse = this.sendSms(alertUser.getPhoneNo(), content, headParamMap);
            ResponseData responseData = JSONObject.parseObject(smsResponse, ResponseData.class);
//            LOGGER.info("[告警短信发送:{}--{}--{}--{}]",alertUser.getPhoneNo(), smsAddr.get(), headParamMap, smsResponse);
            if (!ResponseEnum.SUCCESSS.getCode().equals(responseData.getRespCode())) {
                LOGGER.warn("[告警短信发送异常:{}--{}--{}--{}]", alertUser.getPhoneNo(), smsAddr.get(), headParamMap, smsResponse);
            }
        } catch (Exception e) {
            LOGGER.warn("[告警短信发送异常:{}--{}--{}--{}]", alertUser.getPhoneNo(), smsAddr.get(), headParamMap, e.getMessage());
        }

        try {
            String emailResponse = this.sendEmail(alertUser.getEmail(), content, headParamMap);
            ResponseData responseData = JSONObject.parseObject(emailResponse, ResponseData.class);
//            LOGGER.info("[告警邮件发送:{}--{}--{}--{}]",alertUser.getEmail(), emailAddr.get(), headParamMap, emailResponse);
            if (!ResponseEnum.SUCCESSS.getCode().equals(responseData.getRespCode())) {
                LOGGER.warn("[告警邮件发送异常:{}--{}--{}--{}]", alertUser.getEmail(), emailAddr.get(), headParamMap, emailResponse);
            }
        } catch (Exception e) {
            LOGGER.warn("[告警邮件发送异常:{}--{}--{}--{}]", alertUser.getEmail(), emailAddr.get(), headParamMap, e.getMessage());
        }

        AlertNotice record = new AlertNotice();
        record.setId(alertNotice.getId());
        record.setUpdateTime(new Date());
        record.setNoticeCount(alertNotice.getNoticeCount() + 1);

        alertNoticeDao.updateByPrimaryKeySelective(record);
    }

    private String sendEmail(String email, String content, Map<String, String> headParamMap) throws Exception {
        String emailUrl = emailAddr.get();
        Map<String, Object> emailRequestMap = Maps.newHashMap();
        Map<String, Object> emailBodyMap = Maps.newHashMap();

        emailBodyMap.put("attachmentUrl", "");
        emailBodyMap.put("content", content);
        emailBodyMap.put("cc", Lists.newArrayList());
        emailBodyMap.put("emails", Lists.newArrayList(email));
        emailBodyMap.put("fileBytes", "");
        emailBodyMap.put("fileName", "");
        emailBodyMap.put("kvMap", Maps.newHashMap());
        emailBodyMap.put("subject", "网关告警通知");
        emailBodyMap.put("template", "");

        emailRequestMap.put("request", emailBodyMap);


        String emailJsonStr = JSONObject.toJSONString(emailRequestMap);

        return HttpUtility.httpPost(emailUrl, emailJsonStr, headParamMap);
    }

    private String sendSms(String phoneNo, String content, Map<String, String> headParamMap) throws Exception {
        String smsUrl = smsAddr.get();
        Map<String, Object> smsRequestMap = Maps.newHashMap();
        Map<String, Object> smsBodyMap = Maps.newHashMap();
        smsBodyMap.put("accountId", 0);
        smsBodyMap.put("content", content);
        smsBodyMap.put("desc", "");
        smsBodyMap.put("mobile", phoneNo);
        smsBodyMap.put("type", 0);

        smsRequestMap.put("request", smsBodyMap);

        String smsJsonStr = JSONObject.toJSONString(smsRequestMap);

        return HttpUtility.httpPost(smsUrl, smsJsonStr, headParamMap);
    }

}
